package com.bringspring.workflow.engine.service.impl;

import com.bringspring.common.base.UserInfo;
import com.bringspring.common.database.model.entity.DbLinkEntity;
import com.bringspring.common.model.FormAllModel;
import com.bringspring.common.model.visiual.FormCloumnUtil;
import com.bringspring.common.model.visiual.FormDataModel;
import com.bringspring.common.model.visiual.RecursionForm;
import com.bringspring.common.model.visiual.TableModel;
import com.bringspring.common.model.visiual.fields.FieLdsModel;
import com.bringspring.common.util.JsonUtil;
import com.bringspring.common.util.RandomUtil;
import com.bringspring.common.util.StringUtils;
import com.bringspring.common.util.UserProvider;
import com.bringspring.system.base.exception.WorkFlowException;
import com.bringspring.workflow.engine.entity.FlowEngineEntity;
import com.bringspring.workflow.engine.entity.FlowTaskEntity;
import com.bringspring.workflow.engine.enums.FlowTaskStatusEnum;
import com.bringspring.workflow.engine.model.DataModel;
import com.bringspring.workflow.engine.model.flowtask.FlowTaskForm;
import com.bringspring.workflow.engine.model.flowtask.FlowTaskInfoVO;
import com.bringspring.workflow.engine.service.FlowDynamicService;
import com.bringspring.workflow.engine.service.FlowEngineService;
import com.bringspring.workflow.engine.service.FlowTaskOperatorService;
import com.bringspring.workflow.engine.service.FlowTaskService;
import com.bringspring.workflow.engine.util.FlowDataUtil;
import com.bringspring.workflow.engine.util.FlowUtil;
import com.bringspring.workflow.engine.util.ServiceAllUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 在线开发工作流
 *
 * @author 开发平台组
 * @version V1.0.0
 * @copyright 股份有限公司
 * @date 2021/3/15 9:19
 */
@Slf4j
@Service
public class FlowDynamicServiceImpl implements FlowDynamicService {

    @Autowired
    private FlowTaskService flowTaskService;
    @Autowired
    private FlowEngineService flowEngineService;
    @Autowired
    private FlowTaskOperatorService flowTaskOperatorService;
    @Autowired
    private UserProvider userProvider;
    @Autowired
    private FlowDataUtil flowDataUtil;
    @Autowired
    private ServiceAllUtil serviceUtil;

    @Override
    public FlowTaskInfoVO info(FlowTaskEntity entity, String taskOperatorId) throws WorkFlowException {
        FlowEngineEntity flowEntity = flowEngineService.getInfo(entity.getFlowId());
        List<TableModel> tableModelList = JsonUtil.getJsonToList(flowEntity.getFlowTables(), TableModel.class);
        FlowTaskInfoVO vo = JsonUtil.getJsonToBean(entity, FlowTaskInfoVO.class);
        //formTempJson
        FormDataModel formData = JsonUtil.getJsonToBean(entity.getFlowForm(), FormDataModel.class);
        List<FieLdsModel> list = JsonUtil.getJsonToList(formData.getFields(), FieLdsModel.class);
        DbLinkEntity link = serviceUtil.getDbLink(flowEntity.getDbLinkId());
        Map<String, Object> dataMap = StringUtils.isNotEmpty(entity.getFlowFormContentJson()) ? JsonUtil.stringToMap(entity.getFlowFormContentJson()) : new HashMap<>(16);
        DataModel dataModel = DataModel.builder().dataNewMap(dataMap).fieLdsModelList(list).tableModelList(tableModelList).mainId(entity.getProcessId()).link(link).build();
        Map<String, Object> result = flowDataUtil.info(dataModel);
        vo.setData(JsonUtil.getObjectToString(result));
        return vo;
    }

    @Override
    public void save(String id, FlowTaskForm flowTaskForm) throws WorkFlowException {
        String flowId = flowTaskForm.getFlowId();
        String data = flowTaskForm.getData();
        FlowEngineEntity entity = flowEngineService.getInfo(flowId);
        UserInfo info = userProvider.get();
        String billNo = "单据规则不存在";
        String title = info.getRealName() + "的" + entity.getFullName();
        String formId = RandomUtil.uuId();
        //tableJson
        List<TableModel> tableModelList = JsonUtil.getJsonToList(entity.getFlowTables(), TableModel.class);
        //formTempJson
        FormDataModel formData = JsonUtil.getJsonToBean(entity.getFormData(), FormDataModel.class);
        List<FieLdsModel> list = JsonUtil.getJsonToList(formData.getFields(), FieLdsModel.class);
        RecursionForm recursionForm = new RecursionForm(list, tableModelList);
        List<FormAllModel> formAllModel = new ArrayList<>();
        FormCloumnUtil.recursionForm(recursionForm, formAllModel);
        //主表的单据数据
        Map<String, String> billData = new HashMap<>(16);
        boolean type = id != null;
        if (type) {
            formId = id;
        }
        //表单值
        Map<String, Object> dataMap = JsonUtil.stringToMap(data);
        DbLinkEntity link = serviceUtil.getDbLink(entity.getDbLinkId());
        DataModel dataModel = DataModel.builder().dataNewMap(dataMap).fieLdsModelList(list).tableModelList(tableModelList).mainId(formId).link(link).build();
        Map<String, Object> result = type ? flowDataUtil.update(dataModel) : flowDataUtil.create(dataModel);
        //流程信息
        FlowUtil.saveOrSubmit(flowTaskForm.getTaskId(),flowId,formId,result, FlowTaskStatusEnum.Draft.getCode());
    }

    @Override
    public void submit(String id, FlowTaskForm flowTaskForm) throws WorkFlowException {
        String flowId = flowTaskForm.getFlowId();
        String data = flowTaskForm.getData();
        String freeUserId = flowTaskForm.getFreeApproverUserId();
        Map<String, List<String>> candidateList = flowTaskForm.getCandidateList();
        FlowEngineEntity entity = flowEngineService.getInfo(flowId);
        UserInfo info = userProvider.get();
        String billNo = "单据规则不存在";
        String title = info.getRealName() + "的" + entity.getFullName();
        String formId = RandomUtil.uuId();
        //tableJson
        List<TableModel> tableModelList = JsonUtil.getJsonToList(entity.getFlowTables(), TableModel.class);
        //formTempJson
        FormDataModel formData = JsonUtil.getJsonToBean(entity.getFormData(), FormDataModel.class);
        List<FieLdsModel> list = JsonUtil.getJsonToList(formData.getFields(), FieLdsModel.class);
        List<FormAllModel> formAllModel = new ArrayList<>();
        RecursionForm recursionForm = new RecursionForm(list, tableModelList);
        FormCloumnUtil.recursionForm(recursionForm, formAllModel);
        //主表的单据数据
        Map<String, String> billData = new HashMap<>(16);
        boolean type = id != null;
        if (type) {
            formId = id;
        }
        //表单值
        Map<String, Object> dataMap = JsonUtil.stringToMap(data);
        DbLinkEntity link = serviceUtil.getDbLink(entity.getDbLinkId());
        DataModel dataModel = DataModel.builder().dataNewMap(dataMap).fieLdsModelList(list).tableModelList(tableModelList).mainId(formId).link(link).build();
        Map<String, Object> result = type ? flowDataUtil.update(dataModel) : flowDataUtil.create(dataModel);
        //流程信息
        FlowUtil.saveOrSubmit(flowTaskForm.getTaskId(),flowId,formId,result, FlowTaskStatusEnum.Handle.getCode());
    }

    @Override
    public Map<String, Object> getData(String flowId, String id) throws WorkFlowException {
        FlowTaskEntity entity = flowTaskService.getInfo(id);
        FlowEngineEntity flowentity = flowEngineService.getInfo(flowId);
        List<TableModel> tableModelList = JsonUtil.getJsonToList(flowentity.getFlowTables(), TableModel.class);
        //formTempJson
        FormDataModel formData = JsonUtil.getJsonToBean(entity.getFlowForm(), FormDataModel.class);
        List<FieLdsModel> list = JsonUtil.getJsonToList(formData.getFields(), FieLdsModel.class);
        DbLinkEntity link = serviceUtil.getDbLink(flowentity.getDbLinkId());
        Map<String, Object> dataMap = StringUtils.isNotEmpty(entity.getFlowFormContentJson()) ? JsonUtil.stringToMap(entity.getFlowFormContentJson()) : new HashMap<>(16);
        DataModel dataModel = DataModel.builder().dataNewMap(dataMap).fieLdsModelList(list).tableModelList(tableModelList).mainId(entity.getId()).link(link).convert(true).build();
        Map<String, Object> resultData = flowDataUtil.info(dataModel);
        return resultData;
    }

}
